package egar

import (
	"math"
	"sync/atomic"
	"time"
)

var _lgc_rand_seed int64 = time.Now().Unix()

// random number range is [0-1]
func LcgRand() float64 {
	_lgc_rand_seed = (_lgc_rand_seed * 16807) % 2147483647
	return float64(_lgc_rand_seed) / 2147483647
}

func RandomRange(a, b float64) float64 {
	return LcgRand()*(b-a) + a
}

func MassToRadius(mass float64) float64 {
	return math.Sqrt(mass / math.Pi)
}

func RadiusToMass(radius float64) float64 {
	return radius * radius * math.Pi
}

func RandomPosition() (x float64, y float64) {
	return RandomRange(0, globalConfig.GameMapWidth), RandomRange(0, globalConfig.GameMapHeight)
}

func RandomColor() uint32 {
	rgb := []uint32{0xff, 0x7, uint32(LcgRand() * 0xff)}
	for i := 0; i < len(rgb); i++ {
		j := int32(LcgRand() * float64(len(rgb)))
		rgb[i], rgb[j] = rgb[j], rgb[i]
	}
	return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]
}

var ballIDSequence uint32 = 0

func generateBallID() uint32 {
	return atomic.AddUint32(&ballIDSequence, 1)
}

func checkIntersect(rectTopLeftX, rectTopLeftY, rectBottomRightX, rectBottomRightY, circleCenterX, circleCenterY, circleRadius float64) bool {
	dx := math.Max(0, rectTopLeftX-circleCenterX) + math.Max(0, circleCenterX-rectBottomRightX)
	dy := math.Max(0, rectTopLeftY-circleCenterY) + math.Max(0, circleCenterY-rectBottomRightY)
	return dx*dx+dy*dy <= circleRadius*circleRadius
}

func checkContain(rectTopLeftX, rectTopLeftY, rectBottomRightX, rectBottomRightY, circleCenterX, circleCenterY, circleRadius float64) bool {
	if circleCenterX >= rectTopLeftX && circleCenterX <= rectBottomRightX &&
		circleCenterY >= rectBottomRightY && circleCenterY <= rectTopLeftY {
		distanceX := math.Min(math.Abs(circleCenterX-rectTopLeftX), math.Abs(circleCenterX-rectBottomRightX))
		distanceY := math.Min(math.Abs(circleCenterY-rectTopLeftY), math.Abs(circleCenterY-rectBottomRightY))
		distance := math.Sqrt(distanceX*distanceX + distanceY*distanceY)
		return distance+circleRadius <= circleRadius
	}
	return false
}
